﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

using Rsdn.Janus.ObjectModel;
using Rsdn.SmartApp;

namespace Rsdn.Janus
{
    [Service(typeof(IActiveMessagesService))]
    internal class FeatureActiveMessageService : IActiveMessagesService, IDisposable
    {
        private IMessagesFeature _activeMessagesFeature;

        /// <summary>
        /// Возникает когда активные сообщения изменились.
        /// </summary>
        public event EventHandler ActiveMessagesChanged;

        /// <summary>
        /// Initializes a new instance of the <see cref="FeatureActiveMessageService"/> class.
        /// </summary>
        public FeatureActiveMessageService()
        {
            Features.Instance.OnAfterFeatureActivate += Feature_AfterFeatureActivate;
            _activeMessagesFeature = Features.Instance.ActiveFeature as IMessagesFeature;
            if (_activeMessagesFeature != null)
            {
                _activeMessagesFeature.ActiveMessagesChanged += Feature_ActiveMessagesChanged;
            }
        }

        #region IActiveMessageService Members

        /// <summary>
        /// Должно принудительно вызывать обновление комманд 'имитируя' изменение сообщение
        /// Например при выделений всех сообщений в гриде команды должны 'пересчитаться', но сообщения фактически не изменились
        /// </summary>
        public void UpdateMessageState()
        {
            if (ActiveMessagesChanged != null)
            {
                ActiveMessagesChanged(this, EventArgs.Empty);
            }
        }

        /// <summary>
        /// Активные сообщения.
        /// </summary>
        /// <value>The active messages.</value>
        public IEnumerable<IMsg> ActiveMessages
        {
            get
            {
                return _activeMessagesFeature != null
                    ? _activeMessagesFeature.ActiveMessages
                    : Enumerable.Empty<IMsg>();
            }
        }


        #endregion

        #region IDisposable Members

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            Features.Instance.OnAfterFeatureActivate -= Feature_AfterFeatureActivate;
            if (_activeMessagesFeature != null)
            {
                _activeMessagesFeature.ActiveMessagesChanged -= Feature_ActiveMessagesChanged;
            }
        }

        #endregion

        /// <summary>
        /// Invokes the event ActiveMessagesChanged.
        /// </summary>
        public void InvokeActiveMessagesChanged()
        {
            EventHandler handler = ActiveMessagesChanged;
            if (handler != null)
            {
            #if MNU_TRACE
                        Trace.WriteLine("MNU:InvokeActiveMessagesChanged()"); //MLHIDE
            #endif
                EventArgs e = EventArgs.Empty;
                handler(this, e);
            }
        }

        /// <summary>
        /// Feature_s the after feature activate.
        /// </summary>
        /// <param name="oldFeature">The old feature.</param>
        /// <param name="newFeature">The new feature.</param>
        private void Feature_AfterFeatureActivate(IFeature oldFeature, IFeature newFeature)
        {
#if MNU_TRACE
            Trace.WriteLine(string.Format("MNU:AfterFeatureActivate(old:{0}, new:{1}", oldFeature, newFeature)); //MLHIDE
#endif

            if (_activeMessagesFeature != null)
            {
                _activeMessagesFeature.ActiveMessagesChanged -= Feature_ActiveMessagesChanged;
            }

            _activeMessagesFeature = newFeature as IMessagesFeature;
            if (_activeMessagesFeature != null)
            {
                _activeMessagesFeature.ActiveMessagesChanged += Feature_ActiveMessagesChanged;
            }

            InvokeActiveMessagesChanged();
        }

        /// <summary>
        /// Handles the ActiveMessagesChanged event of the Feature control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Feature_ActiveMessagesChanged(object sender, EventArgs e)
        {
            InvokeActiveMessagesChanged();
        }
    }
}